package com.hdu.dwh.service.impl.cube_impl;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdu.dwh.mapper.cube_mapper.CuboidMapper;
import com.hdu.dwh.pojos.QueryResult;
import com.hdu.dwh.pojos.cube_pojos.Cuboid;
import com.hdu.dwh.pojos.cube_pojos.CuboidDimension;
import com.hdu.dwh.service.TrinoQueryService;
import com.hdu.dwh.service.cube_service.CuboidDimensionService;
import com.hdu.dwh.service.cube_service.CuboidService;
import com.hdu.dwh.utils.CubeUtils;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class CuboidServiceImpl extends ServiceImpl<CuboidMapper, Cuboid> implements CuboidService {
    @Autowired
    private CuboidDimensionService cuboidDimensionService;

    @Autowired
    private TrinoQueryService trinoQueryService;

    @Override
    public Set<Cuboid> getCuboidsByCubeId(Integer id) {
        Set<Cuboid> cuboids = this.lambdaQuery()
            .eq(Cuboid::getCubeId, id)
            .list()
            .stream()
            .collect(java.util.stream.Collectors.toSet());
        for (Cuboid cuboid : cuboids) {
            Set<CuboidDimension> dimensions = this.cuboidDimensionService.getCuboidDimensionsByCuboidId(cuboid.getId());
            cuboid.setDimensions(dimensions);
        }
        for (Cuboid cuboid : cuboids) {
            Set<Cuboid> preLevelCuboids = CubeUtils.getPreLevelCuboids(cuboid.getDimensions(), cuboids);
            Set<Cuboid> nextLevelCuboids = CubeUtils.getNextLevelCuboids(cuboid.getDimensions(), cuboids);
            cuboid.setPreLevelCuboids(preLevelCuboids);
            cuboid.setNextLevelCuboids(nextLevelCuboids);
        }
        return cuboids;
    }

    @Override
    public void removeByCubeId(Integer id) {
        Set<Cuboid> cuboids = this.getCuboidsByCubeId(id);
        for (Cuboid cuboid : cuboids) {
            this.cuboidDimensionService.removeByCuboidId(cuboid.getId());
        }
        this.lambdaUpdate()
            .eq(Cuboid::getCubeId, id)
            .remove();
    }

    @Override
    public QueryResult executeCuboidSQL(String sql) throws Exception {
        log.info("execute cuboid sql: {}", sql);
        return trinoQueryService.executeQuery(sql);
    }
    
}
